PyVISA使用

您所在的位置:网站首页 用python写硬件控制程序 pyvisa PyVISA使用

PyVISA使用

2024-06-03 22:37| 来源: 网络整理| 查看: 265

项目要求

项目上提出自动化测试需求,要求能够对板级信号使用示波器等仪器做自动化测量

实现方案

使用PyVISA 方案实现。 VISA (Virtual Instrument Software Architecture) 是一个用于访问测量仪器和控制计算机之间的接口标准,由美国国家仪器公司(National Instruments)推出,用于实现仪器之间的通信和控制。VISA提供了一组标准API函数,可以实现多种通信协议和连接方式的仪器控制。VISA相比于VXI11更加灵活,支持多种接口(底层协议),比如GPIB,RS232,USB, VXIBus等,对于仪器控制有更强大的功能。在这里插入图片描述 Pyvisa是一个基于Python语言开发的访问VISA资源的工具包。通过调用VISA标准API函数来实现与仪器的通信和控制。Pyvisa提供了一组Python的API函数,可以方便地访问VISA库中的函数和方法,从而实现与仪器的数据读取、写入、控制等操作。Pyvisa相比于LabVIEW,Pyvisa是一种跨平台的软件,可以在Linux,Windows和Mac OS上运行,且其拥有更灵活的用户界面,可以自行定制。

如果该脚本运行在服务器上,建议使用Pycharm Professional 或者VSCode + Remote-SSH 插件进行开发,即本地开发,远程部署或调试。

本例使用SCPI命令访问示波器的VISA库,SCPI命令的格式见示波器软件编程手册

脚本实现功能

(1)连接示波器 注意:电脑并没有使用NI-VISA后台,而是使用纯python代码实现的Pyvisa-py, 因此需要提前安装下 pip install -U pyvisa-py (2)简单设置示波器参数,包括channal 选择,横轴窗口设置,纵轴电压窗口设置,Trigger触发方式选择 (3)波形数据以csv 和图片格式保存到本地 (4)保存示波器的截图到本地

脚本与注释 import time import pyvisa as visa import numpy as np import matplotlib.pyplot as plt import pandas as pd from datetime import datetime from pyvisa.errors import VisaIOError from PIL import Image # rm = visa.ResourceManager('@py') # rm.list_resources() # Tek = rm.open_resource('TCPIPO::10.163.xxx.xxx::INSTR') # Tek.timeout=10000 # print(Tek.query('*IDN?')) # self.inst.write('*RST') # self.inst.write('AUTOSET EXECUTE') class Tektronix_DPO: def __init__(self): self.rm = visa.ResourceManager('@py') self.rm.list_resources() self.inst = self.rm.open_resource('TCPIPO::10.163.xxx.xxx::INSTR') self.inst.timeout=10000 print(self.inst.query('*IDN?')) self.inst.write('CLEAR') self.inst.write('ACQuire:MODe?') self.inst.write('ACQUIRE:STOPAFTER RUNSTOP') self.inst.write('ACQuire:STATE RUN') self.inst.write('autoset EXECUTE') # autoset def set_HORIZONTAL(self, POSITION, SCALE): #horizontal settings self.inst.write('HORIZONTAL:POSITION %s'%POSITION) #position means trigger point on the screen /% self.inst.write('HORIZONTAL:SCALE %se-6'%SCALE) #scale means step /us def open_ch(self,ch): # open channal self.inst.write('DISplay:GLObal:CH%s:STATE ON'%ch) def close_ch(self,ch): # close channal self.inst.write('DISplay:GLObal:CH%s:STATE OFF'%ch) def vertical_ch(self,ch,scale,position): #channal settings, self.inst.write('CH%s:BANDWIDTH FULl'%ch) # at its maximum bandwidth self.inst.write('CH%s:SCAle %sE-3'%(ch,scale)) #channal scale/mv self.inst.write('CH%s:POSition %s'%(ch,position)) #channal divisions above the center graticule self.inst.write('CH%s:COUPLING DC'%ch) # DC coupling self.inst.write('CH%s:TERMINATION 10.0E+5'%ch) #channal input resistence is 1MΩ def trigger_set(self,ch,level): #trigger settings self.inst.write('TRIGGER:A:EDGE:COUPLING DC') # DC trigger coupling with input signal to the trigger circuitry self.inst.write('TRIGGER:A:EDGE:SOURCE CH%s'%ch) self.inst.write('TRIGGER:A:EDGE:SLOPE RISE') #triggers on the rising edge of the signal self.inst.write('TRIGGER:A:LEVEL:CH%s %s'%(ch,level)) # level specifies channal trigger level for seach 1, /V def begin_trigger(self): #start once trigger action self.inst.write('acquire:state 0') # stop self.inst.write('acquire:stopafter SEQUENCE') # single self.inst.write('acquire:state 1') # run self.inst.query('*opc?') # sync def data_caul(self,ch): #calculate the channal value self.inst.write("HEADER 0") self.inst.write('DATA:SOURCE CH%s'%ch) self.inst.write("DAT:ENC SRI") # Signed Binary Format, LSB order self.inst.write("DAT:WIDTH 1") self.inst.write("DAT:START 1") recordLength = int(self.inst.query('horizontal:recordlength?')) self.inst.write("DAT:STOP {0}".format(recordLength)) # Set data stop to match points available # Fetch horizontal scaling factors xinc = float(self.inst.query("WFMO:XINCR?")) xzero = float(self.inst.query("WFMO:XZERO?")) pt_off = int(self.inst.query("WFMO:PT_OFF?")) # Fetch vertical scaling factors ymult = float(self.inst.query("WFMO:YMULT?")) yzero = float(self.inst.query("WFMO:YZERO?")) yoff = float(self.inst.query("WFMO:YOFF?")) # Fetch waveform data and save as csv file rawData = self.inst.query_binary_values('curve?', datatype='b', container=np.array) dataLen = len(rawData) t0 = (-pt_off * xinc) + xzero with open('horizonal_vector.csv',mode='w') as file: for i in range(0,dataLen): xvalues = t0 + xinc * i # Create timestamp for the data point file.write(str(xvalues)) file.write(",") yvalues= float(rawData[i] - yoff) * ymult + yzero # Convert raw ADC value into a floating point value file.write(str(yvalues)) file.write("\n") # plotting the measurement figure data = pd.read_csv("horizonal_vector.csv") data_x = data.iloc[:,0] data_y = data.iloc[:,1] plt.plot(data_x, data_y) plt.title('channel 1') # plot label plt.xlabel('time (seconds)') # x label plt.ylabel('voltage (volts)') # y label print("look for plot window...") plt.savefig('test.png') #save test picture plt.show() def close(self): self.inst.close() self.rm.close() def get_screen(self): self.inst.write("HARDCopy:PORT FILE;") self.inst.write("EXPort:FORMat PNG") self.inst.write("HARDCopy:FILEName \"C:\\est_Temp\\Temp.png\"") self.inst.write("HARDCopy STARt") self.inst.write("FILESystem:READFile \"C:\\Low_Speed_Test_Temp\\Temp.png\"") imgData = self.inst.read_raw() dt = datetime.now() fileName = dt.strftime("DPO70000_%Y%m%d_%H%M%S.png") # Generate a filename with date and time file = open(fileName, "wb") file.write(imgData) file.close() self.inst.write('FILESystem:DELEte \"C:\\Test_Temp\\Temp.png\"') # Delete image file from instrument's hard disk. if __name__ == "__main__": my=Tektronix_DPO() my.set_HORIZONTAL(0,40E-3) my.open_ch(1) my.vertical_ch(1,200,0) my.trigger_set(1,0) my.begin_trigger() my.data_caul(1) my.get_screen() my.close() 参考

【1】TEK DPO系列示波器编程手册 【2】PyVISA官方文档 【3】TEK 技术交流论坛



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3